home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games: Greatest Hits 1996 / Amiga Games: Greatest Hits 1996.iso / userbox / publicdomain / lupe / source / lupe.c next >
C/C++ Source or Header  |  1996-05-31  |  39KB  |  1,418 lines

  1. // Lupe V1.5 - 1995-96 - © Frank Toepper
  2. // a lens
  3. // AmigaOS 3.0+
  4. // Maxon C++ V3
  5. // last changes: 30.May.96
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stream.h>
  10. #include <intuition/intuition.h>
  11. #include <intuition/imageclass.h>
  12. #include <intuition/icclass.h>
  13. #include <intuition/gadgetclass.h>
  14. #include <intuition/intuitionbase.h>
  15. #include <exec/exec.h>
  16. #include <dos/dos.h>
  17. #include <graphics/scale.h>
  18. #include <devices/inputevent.h>
  19. #include <libraries/commodities.h>
  20. #include <libraries/gadtools.h>
  21. #include <graphics/displayinfo.h>
  22. #include <graphics/gfxmacros.h>
  23. #include <graphics/gfxbase.h>
  24. #include <cybergraphics/cybergraphics.h>
  25. #include <clib/dos_protos.h>
  26. #include <clib/intuition_protos.h>
  27. #include <clib/graphics_protos.h>
  28. #include <clib/exec_protos.h>
  29. #include <clib/commodities_protos.h>
  30. #include <clib/gadtools_protos.h>
  31. #include <clib/icon_protos.h>
  32. #include <clib/cybergraphics_protos.h>
  33. #include <pragma/cybergraphics_lib.h>
  34. #include <wbstartup.h>
  35.  
  36. #pragma header
  37.  
  38. #define CYBERARRAY_BPP 3
  39. #define MINWIDTH 88
  40. #define MINHEIGHT 30
  41.  
  42. WORD innerwidth = 150, innerheight = 100, sourcewidth, sourceheight;
  43. WORD scalefac = 5, maxscalefac = 15, minwidth, fixedX = 0, fixedY = 0;
  44. WORD leftoff, topoff, bottomoff, rightoff;
  45. WORD sizeiw, sizeih, winx, winy, winleft = 0, wintop = 11, originX = 0, originY = 0;
  46. WORD textoff;
  47. ULONG cxsigflag, scrdepth;
  48. LONG waitmask = 0, pens[4] = {2, 3, 1, 0};
  49. APTR VisualInfo, cyberdata = NULL;
  50. struct MsgPort *broker_mp, *userport;
  51. struct Task *thistask;
  52. struct Window *mywin;
  53. struct Screen *scr = NULL, *tmpscr;
  54. struct Menu *menu = NULL;
  55. struct MenuItem *item;
  56. struct BitMap *srcbm = NULL, *destbm = NULL, *scrbm;
  57. struct TextFont *screenfont = NULL, *topazfont;
  58. struct InputXpression setoriginix, resetoriginix, showhideix;
  59. struct RastPort *scrrp, destrp, *winrp;
  60. struct Library *CxBase, *GfxBase, *GadToolsBase, *CyberGfxBase, *IconBase;
  61. BYTE timesig, showhidesig;
  62. BOOL hires, newlook, jump = FALSE, fast = FALSE, pubscreenlocked = FALSE, enable = TRUE, cybergfxscreen;
  63. BOOL coords = FALSE, crosshair = FALSE, origin = TRUE, fixed = FALSE, jumpdirect, showhide = TRUE, hide = FALSE;
  64. CxObj *broker, *customcxobj;
  65. Object *propgadget;
  66. char pubscreenname[MAXPUBSCREENNAME];
  67. char coordstring[12], setoriginkey[50] = "lalt o", resetoriginkey[50] = "lalt r", showhidekey[50] = "lalt h";
  68. char title[10];
  69. char *Template = "CX_PRIORITY=P/N/K, FAST=F/S/K, MAXSCALEFACTOR=M/N/K, SCALEFACTOR=S/N/K, WINLEFT=L/N/K, WINTOP=T/N/K, "
  70.                       "WINWIDTH=W/N/K, WINHEIGHT=H/N/K, COORDINATES=C/S/K, CROSSHAIR=R/S/K, SETORIGINKEY=O/K, "
  71.                       "RESETORIGINKEY=K/K, FIXED=D/S/K, SHOWHIDEKEY=SH/K, HIDE/S/K";
  72.  
  73. extern struct IntuitionBase *IntuitionBase;
  74.  
  75. // function declarations for menu
  76. BOOL jumpFunc ();
  77. BOOL fastFunc ();
  78. BOOL AboutFunc ();
  79. BOOL enableFunc ();
  80. BOOL coordsFunc ();
  81. BOOL crosshairFunc ();
  82. BOOL fixedFunc ();
  83. BOOL QuitFunc ();
  84. BOOL hideFunc ();
  85.  
  86. struct EasyStruct es_about = {
  87.    20, 0,
  88.    "Lupe",
  89.    "%s",
  90.    "%s"
  91. };
  92.  
  93. char *era_about[] = {
  94.    "Lupe V1.5 (" __DATE__ ")\n\n"
  95.    "written by:\n"
  96.    "  Frank Toepper\n"
  97.    "  Maxim Gorki Straße 5A\n"
  98.    "  Greifswald\n"
  99.    "  17491\n"
  100.    "  GERMANY\n\n"
  101.    "E-Mail:\n"
  102.    "  toepper@rz.uni-greifswald.de\n"
  103.    "WWW:\n"
  104.    "  http://www.fh-stralsund.de/~rwermke/di.html\n\n"
  105.    "This program is Public Domain",
  106.    "Ok"
  107. };
  108.  
  109. struct NewBroker newbroker = {
  110.    NB_VERSION,
  111.    "Lupe",
  112.    "Lupe V1.5 © 1995-96 Frank Toepper",
  113.    "A magnifing glass program.",
  114.    3,
  115.    COF_SHOW_HIDE,
  116.    0,
  117.    NULL,
  118.    0
  119. };
  120.  
  121. struct BitScaleArgs bsa = {
  122.    // Src Koords
  123.    0, 0,
  124.    innerwidth / scalefac,
  125.    innerheight / scalefac,
  126.    // Src Faktoren
  127.    1, 1,
  128.    0, 0,
  129.    innerwidth,
  130.    innerheight,
  131.    // Dest Faktoren
  132.    scalefac, scalefac,
  133.    // Bitmaps
  134.    NULL, NULL,
  135.    0,
  136.    0, 0,
  137.    0, 0
  138. };
  139.  
  140. struct TextAttr topaz_attr = {
  141.    "topaz.font",
  142.    8,
  143.    0,
  144.    FPF_ROMFONT
  145. };
  146.  
  147. void Putchar (register __d0 char zeichen, register __a3 char *putchdata)
  148. {
  149.    *putchdata++ = zeichen;
  150. }
  151.  
  152. void error (char *formatstring, ...)
  153. {
  154.  APTR args = &formatstring + 1;
  155.  struct EasyStruct easystruct = {
  156.     sizeof (struct EasyStruct),
  157.     0,
  158.     "Error",
  159.     formatstring,
  160.     "Ok"
  161.  };
  162.  
  163.    if (Cli ())
  164.    {
  165.       VPrintf (formatstring, args);
  166.       FPutC (Output (), '\n');
  167.       Flush (Output ());
  168.    }
  169.    else
  170.    {
  171.       EasyRequestArgs (NULL, &easystruct, NULL, args);
  172.    }
  173. }
  174.  
  175. BOOL lockaspublicscreen (struct Screen *screen)
  176. {
  177.  struct List *pubscreenlist;
  178.  struct PubScreenNode *pubscreennode;
  179.  
  180.    if (pubscreenlist = LockPubScreenList ())
  181.    {
  182.       pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
  183.       while (pubscreennode)
  184.       {
  185.          if (pubscreennode->psn_Screen == screen)
  186.          {
  187.             if (LockPubScreen (pubscreennode->psn_Node.ln_Name))
  188.             {
  189.                UnlockPubScreenList ();
  190.                return TRUE;
  191.             }
  192.          }
  193.          pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
  194.       }
  195.       UnlockPubScreenList ();
  196.    }
  197.    return FALSE;
  198. }
  199.  
  200. int setupscreen (struct Screen *selectedscreen)
  201. {
  202.  ULONG id;
  203.  
  204.    jumpdirect = FALSE;
  205.    if (selectedscreen)
  206.    {
  207.       jumpdirect = TRUE;
  208.       if (scr)
  209.       {
  210.           if (VisualInfo) FreeVisualInfo (VisualInfo);
  211.          if (pubscreenlocked) UnlockPubScreen (NULL, scr);
  212.       }
  213.       if (lockaspublicscreen (selectedscreen)) pubscreenlocked = TRUE;
  214.       else pubscreenlocked = FALSE;
  215.       scr = selectedscreen;
  216.    }
  217.    else if (scr)
  218.    {
  219.       if (tmpscr = scr->NextScreen)
  220.       {
  221.          FreeVisualInfo (VisualInfo);
  222.          VisualInfo = NULL;
  223.          if (pubscreenlocked)
  224.          {
  225.             UnlockPubScreen (NULL, scr);
  226.             pubscreenlocked = FALSE;
  227.          }
  228.          if (lockaspublicscreen (tmpscr)) pubscreenlocked = TRUE;
  229.       }
  230.       else
  231.       {
  232.          error ("There is no other screen.");
  233.          return 1;  // not real an error
  234.       }
  235.       scr = tmpscr;
  236.    }
  237.    else if (scr = LockPubScreen (NULL))
  238.    {
  239.       pubscreenlocked = TRUE;
  240.    }
  241.    else
  242.    {
  243.       error ("Can't lock publicscreen.");
  244.       return 2;
  245.    }
  246.    if (!(VisualInfo = GetVisualInfoA (scr, NULL)))
  247.    {
  248.       error ("Can't get visualinfo from screen.");
  249.       return 3;
  250.    }
  251.    cybergfxscreen = FALSE;
  252.    if (CyberGfxBase)
  253.       if ((id = GetVPModeID (&scr->ViewPort)) != INVALID_ID)
  254.          if (IsCyberModeID (id))
  255.             if (GetCyberIDAttr (CYBRIDATTR_BPPIX, id) > 1)
  256.                cybergfxscreen = TRUE;
  257.    return 0;
  258. }
  259.  
  260. void CloseDownScreen ()
  261. {
  262.    if (VisualInfo)
  263.    {
  264.       FreeVisualInfo (VisualInfo);
  265.       VisualInfo = NULL;
  266.    }
  267.    if (scr && pubscreenlocked)
  268.    {
  269.       UnlockPubScreen (NULL, scr);
  270.       pubscreenlocked = FALSE;
  271.    }
  272. }
  273.  
  274. void getoffsets ()
  275. {
  276.  struct DrawInfo *drawinfo;
  277.  APTR sizeobject;
  278.  ULONG attr;
  279.  
  280.    if (screenfont)
  281.    {
  282.       CloseFont (screenfont);
  283.       screenfont = NULL;
  284.    }
  285.    hires = (scr->Flags & SCREENHIRES) != 0;
  286.    hires ? (rightoff = 18) : (rightoff = 13);
  287.    if (drawinfo = GetScreenDrawInfo (scr))
  288.    {
  289.       if (sizeobject = NewObject (NULL, SYSICLASS,
  290.        SYSIA_Which, SIZEIMAGE,
  291.        SYSIA_DrawInfo, drawinfo,
  292.        SYSIA_Size, hires ? SYSISIZE_MEDRES : SYSISIZE_LOWRES,
  293.        TAG_END))
  294.       {
  295.          if (GetAttr (IA_Width, sizeobject, &attr))
  296.          {
  297.             sizeiw = attr;
  298.             rightoff =  (UWORD) attr;
  299.          }
  300.          if (GetAttr (IA_Height, sizeobject, &attr))
  301.          {
  302.             sizeih = attr;
  303.          }
  304.          newlook = (drawinfo->dri_Flags & DRIF_NEWLOOK) && (drawinfo->dri_Depth != 1);
  305.          DisposeObject (sizeobject);
  306.       }
  307.       pens[0] = drawinfo->dri_Pens[FILLTEXTPEN];
  308.       pens[1] = drawinfo->dri_Pens[FILLPEN];
  309.       pens[2] = drawinfo->dri_Pens[TEXTPEN];
  310.       pens[3] = drawinfo->dri_Pens[BACKGROUNDPEN];
  311.       FreeScreenDrawInfo (scr, drawinfo);
  312.    }
  313.    scrrp = &scr->RastPort;
  314.    topoff = scrrp->TxHeight + (UWORD) scr->WBorTop + 1;
  315.    leftoff = scr->WBorLeft;
  316.    scrbm = scrrp->BitMap;
  317.    scrdepth = GetBitMapAttr (scrbm, BMA_DEPTH);
  318.    minwidth = MINWIDTH;
  319.    if (coords)
  320.    {
  321.       bottomoff = sizeih;
  322.       // center the text in the bottomborder
  323.       textoff = (bottomoff + topazfont->tf_YSize >> 1) - topazfont->tf_Baseline;
  324.       // SysIHack or height of screenfont <= 8?
  325.       if ((bottomoff - 2) >= scr->Font->ta_YSize)
  326.       {
  327.          if (screenfont = OpenFont (scr->Font))
  328.          {
  329.             minwidth = 11 * (screenfont->tf_XSize);
  330.             // center the text in the bottomborder
  331.             textoff = (bottomoff + screenfont->tf_YSize >> 1) - screenfont->tf_Baseline;
  332.          }
  333.       }
  334.    }
  335.    else bottomoff = scr->WBorBottom;
  336. }
  337.  
  338. void setwintitle ()
  339. {
  340.  LONG args[] = { (LONG) "Lupe", scalefac };
  341.  
  342.    RawDoFmt ("%s %ld:1", args, (void (*)()) Putchar, title);
  343.    SetWindowTitles (mywin, title, (STRPTR) ~0);
  344. }
  345.  
  346. int allocbm ()
  347. {
  348.    if (destbm) FreeBitMap (destbm);
  349.    if (srcbm) FreeBitMap (srcbm);
  350.    destbm = srcbm = NULL;
  351.    if (cyberdata) FreeVec (cyberdata);
  352.    cyberdata = NULL;
  353.    winx = mywin->Width;
  354.    winy = mywin->Height;
  355.    innerwidth = winx - (leftoff + rightoff);
  356.    innerheight = winy - (topoff + bottomoff);
  357.    sourcewidth = innerwidth / scalefac;
  358.    sourceheight = innerheight / scalefac;
  359.    if (scalefac > 1)
  360.    {
  361.       if (cybergfxscreen)
  362.       {
  363.          if (!(cyberdata = AllocVec (sourcewidth * sourceheight * CYBERARRAY_BPP, MEMF_PUBLIC)))
  364.          {
  365.             error ("Can't allocate %ld Bytes for CyberPixelArray.", sourcewidth * sourceheight * CYBERARRAY_BPP);
  366.             return 1;
  367.          }
  368.          if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR | BMF_MINPLANES, scrbm)))
  369.          {
  370.             error ("'AllocBitMap' for destination bitmap failed.");
  371.             return 3;
  372.          }
  373.       }
  374.       else
  375.       {
  376.          if (!(srcbm = AllocBitMap (sourcewidth, sourceheight, scrdepth, BMF_CLEAR, scrbm)))
  377.          {
  378.             error ("'AllocBitMap' for source bitmap failed.");
  379.             return 2;
  380.          }
  381.          if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR, scrbm)))
  382.          {
  383.             error ("'AllocBitMap' for destination bitmap failed.");
  384.             return 3;
  385.          }
  386.          bsa.bsa_SrcWidth = sourcewidth;
  387.          bsa.bsa_SrcHeight = sourceheight;
  388.          bsa.bsa_DestWidth = innerwidth;
  389.          bsa.bsa_DestHeight = innerheight;
  390.          bsa.bsa_SrcBitMap = srcbm;
  391.          bsa.bsa_DestBitMap = destbm;
  392.          bsa.bsa_XDestFactor = bsa.bsa_YDestFactor = scalefac;
  393.       }
  394.       destrp.BitMap = destbm;
  395.    }
  396.    return 0;
  397. }
  398.  
  399. BOOL makescreensmenu ()
  400. {
  401.  struct NewMenu tmpmenu[] = {
  402.   { NM_SUB, 0, 0, 0, 0, 0 },
  403.   { NM_END, 0, 0, 0, 0, 0 }
  404.  };
  405.  ULONG lock;
  406.  struct List *pubscreenlist;
  407.  struct PubScreenNode *pubscreennode;
  408.  struct MenuItem **itempointer = &menu->FirstItem->NextItem->SubItem;
  409.  int i = 0;
  410.  
  411.    lock = LockIBase (0);
  412.    tmpscr = IntuitionBase->FirstScreen;
  413.    if (tmpscr->NextScreen)
  414.    {
  415.       while (tmpscr = tmpscr->NextScreen)
  416.       {
  417.          tmpmenu[0].nm_Label = tmpscr->DefaultTitle;
  418.          if (pubscreenlist = LockPubScreenList ())
  419.          {
  420.             pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
  421.             while (pubscreennode)
  422.             {
  423.                if (pubscreennode->psn_Screen == tmpscr)
  424.                {
  425.                   tmpmenu[0].nm_Label = pubscreennode->psn_Node.ln_Name;
  426.                   break;
  427.                }
  428.                pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
  429.             }
  430.             UnlockPubScreenList ();
  431.          }
  432.          tmpmenu[0].nm_UserData = tmpscr;
  433.          // each item single created
  434.          if (*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL))
  435.          {
  436.             itempointer = &(*itempointer)->NextItem;
  437.          }
  438.          else error ("Can't create a screensmenu item.");
  439.       }
  440.    }
  441.    else
  442.    {
  443.       tmpmenu[0].nm_Label = "No Other Screen";
  444.       if (*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL))
  445.       {
  446.          (*itempointer)->Flags |= HIGHNONE;
  447.          itempointer = &(*itempointer)->NextItem;
  448.       }
  449.       else error ("Can't create screensmenu.");
  450.    }
  451.    UnlockIBase (lock);
  452.    if (LayoutMenus (menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE))
  453.    {
  454.       return TRUE;
  455.    }
  456.    else error ("Can't layout screensmenu.");
  457.    return FALSE;
  458. }
  459.  
  460. void freescreensmenu (struct MenuItem *menuitem)
  461. {
  462.    if (menuitem)
  463.    {
  464.       freescreensmenu (menuitem->NextItem);
  465.       FreeMenus ((struct Menu *) menuitem);
  466.    }
  467. }
  468.  
  469. BOOL openwin ()
  470. {
  471.  ULONG lock;
  472.  WORD bw, rh;
  473.  struct Rectangle zoom = {
  474.     minwidth + leftoff + rightoff,
  475.     MINHEIGHT + topoff + bottomoff + sizeih,
  476.     -1, -1
  477.  };
  478.  struct NewMenu standartmenu[] = {
  479.    { NM_TITLE, "Project",        0, 0, 0, 0 },
  480.    {  NM_ITEM, "Jump",           "J", 0, 0, jumpFunc },
  481.    {  NM_ITEM, "Jump To Screen", 0, 0, 0, 0 },
  482.    {  NM_ITEM, NM_BARLABEL,      0, 0, 0, 0 },
  483.    {  NM_ITEM, "Enable",         "E", (enable ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, enableFunc },
  484.    {  NM_ITEM, "Fixed",          "D", (fixed ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, fixedFunc },
  485.    {  NM_ITEM, "Fast",           "F", (fast ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, fastFunc },
  486.    {  NM_ITEM, "Coordinates",    "C", (coords ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, coordsFunc },
  487.    {  NM_ITEM, "Crosshair",      "R", (crosshair ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, crosshairFunc },
  488.    {  NM_ITEM, NM_BARLABEL,      0, 0, 0, 0 },
  489.    {  NM_ITEM, "About",          "?", 0, 0, AboutFunc },
  490.    {  NM_ITEM, NM_BARLABEL,      0, 0, 0, 0 },
  491.    {  NM_ITEM, "Hide",           "H", 0, 0, hideFunc },
  492.    {  NM_ITEM, "Quit",           "Q", 0, 0, QuitFunc },
  493.    {  NM_END, 0, 0, 0, 0, 0 }
  494.  };
  495.  
  496.     if (!mywin)
  497.     {
  498.        if (hires) bw = rh = 2;
  499.        else bw = rh = 1;
  500.        // first bring the screen to front
  501.        //  -> screen order in menu correct
  502.        lock = LockIBase (0);
  503.        tmpscr = IntuitionBase->FirstScreen;
  504.        UnlockIBase (lock);
  505.        if (tmpscr != scr)
  506.        {
  507.           if (jumpdirect) ScreenToFront (scr);
  508.           else ScreenToBack (tmpscr);
  509.        }
  510.        if (menu = CreateMenusA (standartmenu, NULL))
  511.        {
  512.           if (makescreensmenu ())
  513.           {
  514.              if (propgadget = (Object *) NewObject (NULL, PROPGCLASS,
  515.               PGA_Freedom,     FREEVERT,
  516.               ICA_TARGET,      ICTARGET_IDCMP,
  517.               PGA_NewLook,     TRUE,
  518.               PGA_Borderless,  newlook,
  519.               PGA_Total,       maxscalefac,
  520.               PGA_Visible,     1,
  521.               PGA_Top,         scalefac - 1,
  522.               GA_RelRight,     bw - sizeiw + 3,
  523.               GA_Top,          topoff + rh,
  524.               GA_Width,        sizeiw - bw - bw - 4,
  525.               GA_RelHeight,    -topoff - sizeih - rh - rh,
  526.               GA_RightBorder,  TRUE,
  527.               TAG_DONE))
  528.              {
  529.                 if (mywin = OpenWindowTags (NULL,
  530.                  WA_Flags,          WFLG_ACTIVATE | WFLG_CLOSEGADGET | WFLG_DEPTHGADGET | WFLG_DRAGBAR
  531.                                      | WFLG_SIZEGADGET | WFLG_SIMPLE_REFRESH | WFLG_NEWLOOKMENUS
  532.                                      | WFLG_NOCAREREFRESH | WFLG_REPORTMOUSE
  533.                                      | WFLG_SIZEBRIGHT | (coords ? WFLG_SIZEBBOTTOM : 0),
  534.                  WA_AutoAdjust,     1,
  535.                  WA_MaxHeight,      -1,
  536.                  WA_MaxWidth,       -1,
  537.                  WA_MinHeight,      MINHEIGHT + topoff + bottomoff,
  538.                  WA_MinWidth,       minwidth + leftoff + rightoff,
  539.                  WA_IDCMP,          IDCMP_CLOSEWINDOW | IDCMP_IDCMPUPDATE | IDCMP_NEWSIZE | IDCMP_MENUPICK
  540.                                      | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS
  541.                                      | IDCMP_MOUSEMOVE | IDCMP_VANILLAKEY | IDCMP_RAWKEY,
  542.                  WA_InnerHeight,    innerheight,
  543.                  WA_InnerWidth,     innerwidth,
  544.                  WA_Left,           winleft,
  545.                  WA_Gadgets,        propgadget,
  546.                  WA_Top,            wintop,
  547.                  WA_PubScreen,      scr,
  548.                  WA_Zoom,           &zoom,
  549.                  TAG_DONE))
  550.                 {
  551.                    // shit patches
  552.                    leftoff = mywin->BorderLeft;
  553.                    bottomoff = mywin->BorderBottom;
  554.                    SetMenuStrip (mywin, menu);
  555.                    setwintitle ();
  556.                    userport = mywin->UserPort;
  557.                    winrp = mywin->RPort;
  558.                    if (screenfont) SetFont (winrp, screenfont);
  559.                    else SetFont (winrp, topazfont);
  560.                    SetAPen (winrp, pens[0]);
  561.                    SetBPen (winrp, pens[1]);
  562.                        waitmask |= 1 << userport->mp_SigBit;
  563.                    return TRUE;
  564.                 }
  565.                 else error ("Can't open window.");
  566.              }
  567.              else error ("Can't create propgadget.");
  568.           }
  569.        }
  570.        else error ("Can't create menu.");
  571.        return FALSE;
  572.     }
  573.     return TRUE;  // win already open
  574. }
  575.  
  576. void closewin ()
  577. {
  578.    if (mywin)
  579.     {
  580.        if (menu) ClearMenuStrip (mywin);
  581.        wintop = mywin->TopEdge;
  582.        winleft = mywin->LeftEdge;
  583.        waitmask &= ~(1 << userport->mp_SigBit);
  584.        CloseWindow (mywin);
  585.        mywin = NULL;
  586.    }
  587.    if (menu)
  588.    {
  589.       freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
  590.       FreeMenus (menu);
  591.       menu = NULL;
  592.    }
  593.    if (propgadget)
  594.    {
  595.        DisposeObject (propgadget);
  596.        propgadget = NULL;
  597.     }
  598.    if (srcbm)
  599.    {
  600.        FreeBitMap (srcbm);
  601.        srcbm = NULL;
  602.    }
  603.    if (destbm)
  604.    {
  605.        FreeBitMap (destbm);
  606.        destbm = NULL;
  607.    }
  608.    if (cyberdata)
  609.    {
  610.        FreeVec (cyberdata);
  611.        cyberdata = NULL;
  612.    }
  613. }
  614.  
  615. BOOL screen_is_still_open ()
  616. {
  617.     tmpscr = IntuitionBase->FirstScreen;
  618.     while (tmpscr)
  619.      {
  620.          if (tmpscr == scr) return TRUE;
  621.          tmpscr = tmpscr->NextScreen;
  622.      }
  623.     return FALSE;
  624. }
  625.  
  626. BOOL showwindow ()
  627. {
  628.  BOOL returnvalue = TRUE;
  629.  
  630.       if (!mywin)
  631.       {
  632.           if (!screen_is_still_open ()) scr = NULL;
  633.           try
  634.           {
  635.              if (setupscreen (scr)) throw 1;
  636.             getoffsets ();
  637.            if (!openwin ()) throw 2;
  638.            if (allocbm ()) throw 3;
  639.         }
  640.         catch (int)
  641.         {
  642.             returnvalue = FALSE;
  643.         }
  644.       }
  645.       return returnvalue;
  646. }
  647.  
  648. void hidewindow ()
  649. {
  650.     closewin ();
  651.     CloseDownScreen ();
  652. }
  653.  
  654. void refresh ()
  655. {
  656.  WORD x, y, xoff = 0, yoff = 0;
  657.  
  658.     if (mywin)
  659.     {
  660.        if (fixed)
  661.        {
  662.           x = fixedX;
  663.           y = fixedY;
  664.        }
  665.        else
  666.        {
  667.           x = scr->MouseX;
  668.           y = scr->MouseY;
  669.        }
  670.        // print the coordinates
  671.        if (coords)
  672.        {
  673.           LONG args[] = {x - originX, y - originY};
  674.           memset (coordstring, ' ', 11);
  675.           RawDoFmt ("%ld,%ld", args, (void (*)()) Putchar, coordstring);
  676.           coordstring[strlen (coordstring)] = ' ';
  677.           Move (winrp, leftoff, mywin->Height - textoff);
  678.           Text (winrp, coordstring, 11);
  679.        }
  680.        // adjust the coordinates
  681.        x -= sourcewidth >> 1;
  682.        y -= sourceheight >> 1;
  683.        if (x < 0)
  684.        {
  685.           xoff = x;
  686.           x = 0;
  687.        }
  688.        else if (x > (scr->Width - sourcewidth))
  689.        {
  690.           xoff = -(scr->Width - sourcewidth - x);
  691.           x = scr->Width - sourcewidth;
  692.        }
  693.        if (y < 0)
  694.        {
  695.           yoff = y;
  696.           y = 0;
  697.        }
  698.        else if (y > (scr->Height - sourceheight))
  699.        {
  700.           yoff = -(scr->Height - sourceheight - y);
  701.           y = scr->Height - sourceheight;
  702.        }
  703.        // calculate the crosshair
  704.        if (crosshair)
  705.        {
  706.           xoff = scalefac * ((sourcewidth >> 1) + xoff) + (scalefac >> 1);
  707.           yoff = scalefac * ((sourceheight >> 1) + yoff) + (scalefac >> 1);
  708.        }
  709.        if (scalefac > 1)
  710.        {
  711.           // blit and scale
  712.           if (cybergfxscreen)
  713.           {
  714.              // BitMapScale don't work with bitmaps >8 Bit (CyberGfx 2.15)
  715.              ReadPixelArray (cyberdata, 0, 0, sourcewidth * CYBERARRAY_BPP, scrrp, x, y, sourcewidth, sourceheight, RECTFMT_RGB);
  716.              ScalePixelArray (cyberdata, sourcewidth, sourceheight, sourcewidth * CYBERARRAY_BPP, &destrp, 0, 0, sourcewidth * scalefac, sourceheight * scalefac, RECTFMT_RGB);
  717.           }
  718.           else
  719.           {
  720.              BltBitMap (scrbm, x, y, srcbm, 0, 0, sourcewidth, sourceheight, ABNC | ABC, ~0, NULL);
  721.              BitMapScale (&bsa);
  722.           }
  723.           // draw the crosshair
  724.           if (crosshair)
  725.           {
  726.              Move (&destrp, xoff, 0);
  727.              Draw (&destrp, xoff, sourceheight * scalefac - 1);
  728.              Move (&destrp, 0, yoff);
  729.              Draw (&destrp, sourcewidth * scalefac - 1, yoff);
  730.           }
  731.           mywin->Flags &= ~SIZEGADGET;
  732.           if ((winx == mywin->Width) && (winy == mywin->Height))
  733.              BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  734.           mywin->Flags |= SIZEGADGET;
  735.        }
  736.        else  // 1:1 - mode
  737.        {
  738.           mywin->Flags &= ~SIZEGADGET;
  739.           if ((winx == mywin->Width) && (winy == mywin->Height))
  740.           {
  741.              BltBitMapRastPort (scrbm, x, y, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  742.              // draw the crosshair in 1:1 - mode
  743.              if (crosshair)
  744.              {
  745.                 SetDrMd (winrp, COMPLEMENT);
  746.                 Move (winrp, leftoff + xoff, topoff);
  747.                 Draw (winrp, leftoff + xoff, topoff + innerheight - 1);
  748.                 Move (winrp, leftoff, topoff + yoff);
  749.                 Draw (winrp, leftoff + innerwidth - 1, topoff + yoff);
  750.                 SetDrMd (winrp, JAM2);
  751.              }
  752.           }
  753.           mywin->Flags |= SIZEGADGET;
  754.        }
  755.     }
  756. }
  757.  
  758. void CxFunction (CxMsg *cxm, CxObj *co)
  759. {
  760.  struct InputEvent *ie = (struct InputEvent *) CxMsgData (cxm);
  761.  
  762.    if (origin)
  763.    {
  764.       if (MatchIX (ie, &setoriginix))
  765.       {
  766.          originX = scr->MouseX;
  767.          originY = scr->MouseY;
  768.          DisposeCxMsg (cxm);
  769.          return;
  770.       }
  771.       if (MatchIX (ie, &resetoriginix))
  772.       {
  773.          originX = originY = 0;
  774.          DisposeCxMsg (cxm);
  775.          return;
  776.       }
  777.    }
  778.    if (showhide)
  779.    {
  780.        if (MatchIX (ie, &showhideix))
  781.        {
  782.            Signal (thistask, 1 << showhidesig);
  783.        }
  784.    }
  785.    if ((ie->ie_Class == IECLASS_TIMER) || fast)
  786.       Signal (thistask, 1 << timesig);
  787. }
  788.  
  789. BOOL initbroker ()
  790. {
  791.  LONG errorcode;
  792.  
  793.    if (broker_mp = CreateMsgPort ())
  794.    {
  795.       newbroker.nb_Port = broker_mp;
  796.       cxsigflag = 1 << broker_mp->mp_SigBit;
  797.       if (broker = CxBroker (&newbroker, &errorcode))
  798.       {
  799.          if (customcxobj = CxCustom (CxFunction, 0))
  800.          {
  801.             if (!CxObjError (customcxobj))
  802.             {
  803.                AttachCxObj (broker, customcxobj);
  804.                if (ParseIX (setoriginkey, &setoriginix) || ParseIX (resetoriginkey, &resetoriginix))
  805.                {
  806.                   origin = FALSE;
  807.                   error ("Can't init a Hotkey.\n%s disabled.", "'Set Origin'");
  808.                }
  809.                if (ParseIX (showhidekey, &showhideix))
  810.                {
  811.                    showhide = FALSE;
  812.                   error ("Can't init a Hotkey.\n%s disabled.", "'Show/Hide Window'");
  813.                }
  814.                ActivateCxObj (broker, 1);
  815.                return TRUE;
  816.             }
  817.             DeleteCxObj (customcxobj);
  818.          }
  819.          else error ("Can't create commodity-custom-objekt.");
  820.          DeleteCxObjAll (broker);
  821.       }
  822.       else if (errorcode == CBERR_SYSERR)
  823.          error ("Can't create commodity-broker-objekt.");
  824.       DeleteMsgPort (broker_mp);
  825.    }
  826.    else error ("Can't create messageport for commodity-broker");
  827.    return FALSE;
  828. }
  829.  
  830. // enable-flag only
  831. void setmenu ()
  832. {
  833.  struct MenuItem *mitem;
  834.  
  835.     if (mywin)
  836.     {
  837.        ClearMenuStrip (mywin);
  838.        mitem = ItemAddress (menu, FULLMENUNUM (0, 3, NOSUB));
  839.        if (enable) mitem->Flags |= CHECKED;
  840.           else mitem->Flags &= ~CHECKED;
  841.        ResetMenuStrip (mywin, menu);
  842.     }
  843. }
  844.  
  845. BOOL reopenwin ()
  846. {
  847.    closewin ();
  848.    getoffsets ();
  849.    if (!openwin ()) return FALSE;
  850.    if (allocbm ()) return FALSE;
  851.    jump = TRUE;
  852.    return TRUE;
  853. }
  854.  
  855. BOOL setpropgad ()
  856. {
  857.    if (allocbm ()) return FALSE;
  858.    SetAttrs (propgadget, PGA_Top, scalefac - 1);
  859.    RefreshGList ((struct Gadget *) propgadget, mywin, NULL, 1);
  860.     setwintitle ();
  861.    return TRUE;
  862. }
  863.  
  864. BOOL menupick (UWORD code)
  865. {
  866.  BOOL returnvalue = TRUE;
  867.  static BOOL (*func)();
  868.  
  869.    while ((code != MENUNULL) && returnvalue && !jump)
  870.    {
  871.       item = ItemAddress (menu, code);
  872.       if (SUBNUM (code) != NOSUB)
  873.       {
  874.          if (GTMENUITEM_USERDATA (item))  // 'no other screen'-submenu == 0
  875.          {
  876.             try
  877.             {
  878.                if (setupscreen ((struct Screen *) GTMENUITEM_USERDATA (item))) throw 1;
  879.                closewin ();
  880.                getoffsets ();
  881.                if (!openwin ()) throw 2;
  882.                if (allocbm ()) throw 3;
  883.             }
  884.             catch (int)
  885.             {
  886.                returnvalue = FALSE;
  887.             }
  888.             jump = TRUE;
  889.          }
  890.       }
  891.       else
  892.       {
  893.          func = (BOOL (*)()) GTMENUITEM_USERDATA (item);
  894.          returnvalue = func ();
  895.       }
  896.       if (!jump) code = item->NextSelect;
  897.    }
  898.    return returnvalue;
  899. }
  900.  
  901. BOOL vanillakey (UWORD code)
  902. {
  903.  BOOL returnvalue = TRUE;
  904.  
  905.    switch (code)
  906.    {
  907.     case 'J':
  908.     case 'j':
  909.       returnvalue = jumpFunc ();
  910.       break;
  911.     case 'E':
  912.     case 'e':
  913.       enable = !enable;
  914.       ActivateCxObj (broker, enable);
  915.       setmenu ();
  916.     case 'F':
  917.     case 'f':
  918.       fast = !fast;
  919.       break;
  920.     case 'C':
  921.     case 'c':
  922.       coords = !coords;
  923.       returnvalue = reopenwin ();
  924.       break;
  925.     case 'R':
  926.     case 'r':
  927.       crosshair = !crosshair;
  928.       break;
  929.     case 'O':
  930.     case 'o':
  931.       originX = scr->MouseX;
  932.       originY = scr->MouseY;
  933.       break;
  934.     case 'K':
  935.     case 'k':
  936.       originX = originY = 0;
  937.       break;
  938.     case 'D':
  939.     case 'd':
  940.       fixed = !fixed;
  941.       break;
  942.     case '?':
  943.     case 'A':
  944.     case 'a':
  945.          AboutFunc ();
  946.       break;
  947.     case 'H':
  948.     case 'h':
  949.         returnvalue = hideFunc ();
  950.         break;
  951.     case 'Q':
  952.     case 'q':
  953.     case 27:  // ESC
  954.       returnvalue = FALSE;
  955.       break;
  956.     case '+':
  957.       if (scalefac < maxscalefac)
  958.       {
  959.          scalefac++;
  960.          returnvalue = setpropgad ();
  961.       }
  962.       break;
  963.     case '-':
  964.       if (scalefac > 1)
  965.       {
  966.          scalefac--;
  967.          returnvalue = setpropgad ();
  968.       }
  969.       break;
  970.    }
  971.    return returnvalue;
  972. }
  973.  
  974. void rawkey (UWORD code, UWORD qualifier)
  975. {
  976.  BOOL returnvalue = TRUE;
  977.  
  978.    switch (code)
  979.    {
  980.     // up
  981.     case 76:
  982.          if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  983.       {
  984.          fixedY -= sourceheight - 1;
  985.          if (fixedY < 0) fixedY = 0;
  986.       }
  987.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  988.       {
  989.          fixedY = 0;
  990.       }
  991.          else if (fixedY) fixedY--;
  992.       break;
  993.     // down
  994.     case 77:
  995.          if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  996.       {
  997.          fixedY += sourceheight - 1;
  998.          if (fixedY > (scr->Height - 1)) fixedY = scr->Height - 1;
  999.       }
  1000.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1001.       {
  1002.          fixedY = scr->Height - 1;
  1003.       }
  1004.             else if (fixedY < (scr->Height - 1)) fixedY++;
  1005.          break;
  1006.     // right
  1007.     case 78:
  1008.          if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1009.       {
  1010.          fixedX += sourcewidth - 1;
  1011.          if (fixedX > (scr->Width - 1)) fixedX = scr->Width - 1;
  1012.       }
  1013.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1014.       {
  1015.          fixedX = scr->Width - 1;
  1016.       }
  1017.          else if (fixedX < (scr->Width - 1)) fixedX++;
  1018.       break;
  1019.     // left
  1020.     case 79:
  1021.          if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1022.       {
  1023.          fixedX -= sourcewidth - 1;
  1024.          if (fixedX < 0) fixedX = 0;
  1025.       }
  1026.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1027.       {
  1028.          fixedX = 0;
  1029.       }
  1030.          else if (fixedX) fixedX--;
  1031.       break;
  1032.    }
  1033. }
  1034.  
  1035. void processmsg ()
  1036. {
  1037.  struct IntuiMessage *intuimsg = NULL, m;
  1038.  CxMsg *msg;
  1039.  BOOL cont = TRUE, fixedmove = FALSE;
  1040.  LONG sigmask, msgid, msgtype;;
  1041.  ULONG lock;
  1042.  
  1043.    waitmask |= (1 << timesig) | (1 << showhidesig) | cxsigflag | SIGBREAKF_CTRL_C;
  1044.    while (cont)
  1045.    {
  1046.       sigmask = Wait (waitmask);
  1047.       if (sigmask & cxsigflag)
  1048.       {
  1049.          while (msg = (CxMsg *) GetMsg (broker_mp))
  1050.          {
  1051.             msgid = CxMsgID (msg);
  1052.             msgtype = CxMsgType (msg);
  1053.             ReplyMsg ((struct Message *) msg);
  1054.             switch (msgtype)
  1055.             {
  1056.              case CXM_COMMAND:
  1057.                switch (msgid)
  1058.                {
  1059.                 case CXCMD_APPEAR:
  1060.                     cont = showwindow ();
  1061.                     break;
  1062.                 case CXCMD_DISAPPEAR:
  1063.                     hidewindow ();
  1064.                     break;
  1065.                 case CXCMD_DISABLE:
  1066.                   ActivateCxObj (broker, 0);
  1067.                   enable = FALSE;
  1068.                   setmenu ();
  1069.                   break;
  1070.                 case CXCMD_ENABLE:
  1071.                   ActivateCxObj (broker, 1);
  1072.                   enable = TRUE;
  1073.                   setmenu ();
  1074.                   break;
  1075.                 case CXCMD_UNIQUE:
  1076.                 case CXCMD_KILL:
  1077.                   cont = FALSE;
  1078.                   break;
  1079.                }
  1080.             }
  1081.          } // while (msg
  1082.       }
  1083.       if (sigmask & (1 << userport->mp_SigBit))
  1084.       {
  1085.          jump = FALSE;
  1086.          while (intuimsg = (struct IntuiMessage *) GetMsg (userport))
  1087.          {
  1088.             CopyMem ((char *) intuimsg, (char *) &m, (long) sizeof (struct IntuiMessage));
  1089.             ReplyMsg ((struct Message *) intuimsg);
  1090.             switch (m.Class)
  1091.             {
  1092.              case IDCMP_CLOSEWINDOW:
  1093.                cont = FALSE;
  1094.                break;
  1095.              case IDCMP_NEWSIZE:
  1096.                if (allocbm ()) cont = FALSE;
  1097.                break;
  1098.              case IDCMP_IDCMPUPDATE:
  1099.                ULONG h;
  1100.                GetAttr (PGA_Top, propgadget, &h);
  1101.                if (++h != scalefac)
  1102.                {
  1103.                   scalefac = h;
  1104.                   if (allocbm ()) cont = FALSE;
  1105.                   setwintitle ();
  1106.                }
  1107.                break;
  1108.              case IDCMP_MENUPICK:
  1109.                  cont = menupick (m.Code);
  1110.                break;
  1111.              case IDCMP_ACTIVEWINDOW:
  1112.                SetAPen (winrp, pens[0]);
  1113.                SetBPen (winrp, pens[1]);
  1114.                ClearMenuStrip (mywin);
  1115.                freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
  1116.                if (makescreensmenu ()) SetMenuStrip (mywin, menu);
  1117.                else cont = FALSE;
  1118.                break;
  1119.              case IDCMP_INACTIVEWINDOW:
  1120.                SetAPen (winrp, pens[2]);
  1121.                SetBPen (winrp, pens[3]);
  1122.                break;
  1123.              case IDCMP_MOUSEBUTTONS:
  1124.                if (fixed)
  1125.                {
  1126.                   if (m.Code == SELECTDOWN) fixedmove = TRUE;
  1127.                   else fixedmove = FALSE;
  1128.                }
  1129.                break;
  1130.              case IDCMP_MOUSEMOVE:
  1131.                if (fixedmove)
  1132.                {
  1133.                   fixedX = scr->MouseX;
  1134.                   fixedY = scr->MouseY;
  1135.                }
  1136.                break;
  1137.              case IDCMP_VANILLAKEY:
  1138.                  cont = vanillakey (m.Code);
  1139.                break;
  1140.              case IDCMP_RAWKEY:
  1141.                  rawkey (m.Code, m.Qualifier);
  1142.                  break;
  1143.             }
  1144.             if (jump) break;
  1145.          } // while (intuimsg
  1146.       }
  1147.       if ((sigmask & (1 << showhidesig)) && cont)
  1148.       {
  1149.            if (mywin) hidewindow ();
  1150.            else showwindow ();
  1151.       }
  1152.       if ((sigmask & (1 << timesig)) && cont)
  1153.       {
  1154.          if (mywin)
  1155.          {
  1156.              // refresh only if we living on the active screen
  1157.              lock = LockIBase (0);
  1158.              tmpscr = IntuitionBase->ActiveScreen;
  1159.              UnlockIBase (lock);
  1160.              if (scr == tmpscr) refresh ();
  1161.          }
  1162.       }
  1163.       if (sigmask & SIGBREAKF_CTRL_C)
  1164.       {
  1165.          cont = FALSE;
  1166.       }
  1167.    }
  1168. }
  1169.  
  1170. BOOL checkmenuitem (BOOL &value)
  1171. {
  1172.    if (!value && (item->Flags & CHECKED)) value = TRUE;
  1173.    else if (value && !(item->Flags & CHECKED)) value = FALSE;
  1174.    return TRUE;
  1175. }
  1176.  
  1177. BOOL fixedFunc ()
  1178. {
  1179.    return checkmenuitem (fixed);
  1180. }
  1181.  
  1182. BOOL fastFunc ()
  1183. {
  1184.    return checkmenuitem (fast);
  1185. }
  1186.  
  1187. BOOL crosshairFunc ()
  1188. {
  1189.    return checkmenuitem (crosshair);
  1190. }
  1191.  
  1192. BOOL AboutFunc ()
  1193. {
  1194.    EasyRequestArgs (NULL, &es_about, NULL, era_about);
  1195.    return TRUE;
  1196. }
  1197.  
  1198. BOOL jumpFunc ()
  1199. {
  1200.  int returnvalue;
  1201.  
  1202.    if (!(returnvalue = setupscreen (NULL)))
  1203.    {
  1204.       return reopenwin ();
  1205.    }
  1206.    else if (returnvalue == 1) return TRUE;      // no other screen
  1207.    return FALSE;
  1208. }
  1209.  
  1210. BOOL coordsFunc ()
  1211. {
  1212.    if (!coords && (item->Flags & CHECKED)) coords = TRUE;
  1213.    else if (coords && !(item->Flags & CHECKED)) coords = FALSE;
  1214.    else return TRUE;  // nothing changed
  1215.    return reopenwin ();
  1216. }
  1217.  
  1218. BOOL enableFunc ()
  1219. {
  1220.    if (item->Flags & CHECKED)
  1221.    {
  1222.       ActivateCxObj (broker, 1);
  1223.       enable = TRUE;
  1224.    }
  1225.    else if (!(item->Flags & CHECKED))
  1226.    {
  1227.       ActivateCxObj (broker, 0);
  1228.       enable = FALSE;
  1229.    }
  1230.    return TRUE;
  1231. }
  1232.  
  1233. BOOL hideFunc ()
  1234. {
  1235.       hidewindow ();
  1236.       jump = TRUE;
  1237.     return TRUE;
  1238. }
  1239.  
  1240. BOOL QuitFunc ()
  1241. {
  1242.    return FALSE;
  1243. }
  1244.  
  1245. BOOL argbool (char **argv, char *name, BOOL def)
  1246. {
  1247. char *value;
  1248.  
  1249.    if (value = (char *) FindToolType ((UBYTE **) argv, name))
  1250.    {
  1251.       if ((MatchToolValue (value, "YES")) || (MatchToolValue (value, "ON"))) return TRUE;
  1252.       if ((MatchToolValue (value, "OFF")) || (MatchToolValue (value, "NO"))) return FALSE;
  1253.    }
  1254.    return def;
  1255. }
  1256.  
  1257. LONG argint (char **argv, UBYTE *name, LONG def)
  1258. {
  1259. APTR value;
  1260. LONG returnvalue;
  1261.  
  1262.    if (value = FindToolType ((UBYTE **) argv, name))
  1263.       if (StrToLong ((UBYTE *) value, &returnvalue)) return returnvalue;
  1264.    return def;
  1265. }
  1266.  
  1267. void argstring (char *result, char **argv, char *name)
  1268. {
  1269.  char *value;
  1270.  
  1271.    if (value = FindToolType ((UBYTE **) argv, name))
  1272.       strncpy (result, value, 50);
  1273. }
  1274.  
  1275. void readargs ()
  1276. {
  1277.  // first time always the tooltypes will be evaluated
  1278.  // if we started from Cli the tooltypes can be overloaded
  1279.  char programname[32];
  1280.  char **argv;
  1281.  struct DiskObject *programicon;
  1282.  struct RDArgs * rdargs;
  1283.  LONG args[15];
  1284.  struct DrawInfo *drawinfo;
  1285.  
  1286.    wintop = scr->RastPort.TxHeight + (UWORD) scr->WBorTop + 1;
  1287.    // make window as square as possible
  1288.    if (drawinfo = GetScreenDrawInfo (scr))
  1289.    {
  1290.       innerheight = innerwidth * drawinfo->dri_Resolution.X / drawinfo->dri_Resolution.Y;
  1291.       FreeScreenDrawInfo (scr, drawinfo);
  1292.    }
  1293.    // a Maxon C++ flag (wbstartup.h)
  1294.    if (_wbflag) strcpy (programname, thistask->tc_Node.ln_Name);
  1295.    else GetProgramName (programname, 32);
  1296.    if (IconBase = OpenLibrary ("icon.library", 37))
  1297.    {
  1298.       if (programicon = GetDiskObject (programname))
  1299.       {
  1300.          argv = programicon->do_ToolTypes;
  1301.          newbroker.nb_Pri = argint (argv, "CX_Priority", newbroker.nb_Pri);
  1302.          fast = argbool (argv, "Fast", fast);
  1303.          maxscalefac = argint (argv, "MaxScaleFactor", maxscalefac);
  1304.          scalefac = argint (argv, "ScaleFactor", scalefac);
  1305.          winleft = argint (argv, "WinLeft", winleft);
  1306.          wintop = argint (argv, "WinTop", wintop);
  1307.          innerheight = argint (argv, "WinHeight", innerheight);
  1308.          innerwidth = argint (argv, "WinWidth", innerwidth);
  1309.          coords = argbool (argv, "Coordinates", coords);
  1310.          crosshair = argbool (argv, "Crosshair", crosshair);
  1311.          argstring (setoriginkey, argv, "SetOriginKey");
  1312.          argstring (resetoriginkey, argv, "ResetOriginKey");
  1313.          fixed = argbool (argv, "Fixed", fixed);
  1314.          argstring (showhidekey, argv, "ShowHideKey");
  1315.          hide = argbool (argv, "Hide", hide);
  1316.          FreeDiskObject (programicon);
  1317.       }
  1318.       CloseLibrary (IconBase);
  1319.    }
  1320.    if (Cli ())
  1321.    {
  1322.       memset (args, '\0', sizeof (args));
  1323.       args[1] = fast;
  1324.       args[8] = coords;
  1325.       args[9] = crosshair;
  1326.       args[12] = fixed;
  1327.       args[14] = hide;
  1328.       if (rdargs = ReadArgs (Template, args, NULL))
  1329.       {
  1330.          if (args[0]) newbroker.nb_Pri = *(LONG *) args[0];
  1331.          fast = args[1];
  1332.          if (args[2]) maxscalefac = *(LONG *) args[2];
  1333.          if (args[3]) scalefac = *(LONG *) args[3];
  1334.          if (args[4]) winleft = *(LONG *) args[4];
  1335.          if (args[5]) wintop = *(LONG *) args[5];
  1336.          if (args[6]) innerwidth = *(LONG *) args[6];
  1337.          if (args[7]) innerheight = *(LONG *) args[7];
  1338.          coords = args[8];
  1339.          crosshair = args[9];
  1340.          if (args[10]) strncpy (setoriginkey, (char *) args[10], 50);
  1341.          if (args[11]) strncpy (resetoriginkey, (char *) args[11], 50);
  1342.          fixed = args[12];
  1343.          if (args[13]) strncpy (showhidekey, (char *) args[13], 50);
  1344.          hide = args[14];
  1345.          FreeArgs (rdargs);
  1346.       }
  1347.    }
  1348.    if (maxscalefac < 5) maxscalefac = 5;
  1349.    // not lower than innerheight or innerwidth
  1350.    // otherwise 'innerheight / scalefac' or 'innerwidth / scalefac'
  1351.    // can go to 0 -> 'AllocBitMap ()' failed
  1352.    if (maxscalefac > MINHEIGHT) maxscalefac = MINHEIGHT;
  1353.    if (scalefac > maxscalefac) scalefac = maxscalefac;
  1354.    if (innerheight < MINHEIGHT) innerheight = MINHEIGHT;
  1355.    if (innerwidth < MINWIDTH) innerwidth = MINWIDTH;
  1356. }
  1357.  
  1358. void main ()
  1359. {
  1360.    if (CxBase = OpenLibrary ("commodities.library", 37))
  1361.    {
  1362.       if (GfxBase = OpenLibrary ("graphics.library", 39))
  1363.       {
  1364.          if (GadToolsBase = OpenLibrary ("gadtools.library", 37))
  1365.          {
  1366.             CyberGfxBase = OpenLibrary ("cybergraphics.library", 40);
  1367.             InitRastPort (&destrp);
  1368.             SetDrMd (&destrp, COMPLEMENT);
  1369.             thistask = FindTask (NULL);
  1370.             if (topazfont = OpenFont (&topaz_attr))
  1371.             {
  1372.                if (!setupscreen (NULL))
  1373.                {
  1374.                   readargs ();
  1375.                   getoffsets ();
  1376.                   try
  1377.                   {
  1378.                       if (!hide)
  1379.                       {
  1380.                           if (!openwin ()) throw 1;
  1381.                           if (allocbm ()) throw 2;
  1382.                        }
  1383.                         if ((timesig = AllocSignal (-1L)) != -1)
  1384.                      {
  1385.                            if ((showhidesig = AllocSignal (-1L)) != -1)
  1386.                            {
  1387.                            if (initbroker ())
  1388.                               {
  1389.                                  processmsg ();
  1390.                                  DeleteCxObjAll (broker);
  1391.                                  DeleteMsgPort (broker_mp);
  1392.                               }
  1393.                               FreeSignal (showhidesig);
  1394.                            }
  1395.                         FreeSignal (timesig);
  1396.                      }
  1397.                      else error ("Can't allocate signal");
  1398.                   }
  1399.                   catch (int) { }
  1400.                   closewin ();
  1401.                   CloseDownScreen ();
  1402.                }
  1403.                CloseFont (topazfont);
  1404.                if (screenfont) CloseFont (screenfont);
  1405.             }
  1406.             else error ("Can't open Topas.font");
  1407.             if (CyberGfxBase) CloseLibrary (CyberGfxBase);
  1408.             CloseLibrary (GadToolsBase);
  1409.          }
  1410.          else error ("can't open '%s' version %ld or higher.", "gadtools.library", 37L);
  1411.          CloseLibrary (GfxBase);
  1412.       }
  1413.       else error ("can't open '%s' version %ld or higher.", "graphics.library", 39L);
  1414.       CloseLibrary (CxBase);
  1415.    }
  1416.    else error ("can't open '%s' version %ld or higher.", "commodities.library", 37L);
  1417. }
  1418.